package lightObjects;

import java.util.ArrayList;
import java.util.List;

import utils.ColorRGB;
import utils.Point3D;
import utils.Ray;
import utils.Vector;
import main.Parseable;
import main.Parser;
import main.Parser.ParseException;

public class PointLight implements lightObject, Parseable {

    private ColorRGB color;
    private Point3D position;
    private Vector attenuation;

    public PointLight() {
	this.color = new ColorRGB(1, 1, 1);
	this.attenuation = new Vector(1, 0, 0);
    }

    public PointLight(ColorRGB color, Point3D position) {
	this.color = new ColorRGB(color);
	this.position = new Point3D(position);
	this.attenuation = new Vector(1, 0, 0);

	finalizeObject();
    }

    public boolean setParameter(String name, String[] args) throws ParseException {
	if (name.equals("color")) {
	    if (args.length != 3) {
		System.out.println("bad parameters");
		return false;
	    }
	    color = new ColorRGB(Parser.stringArrToDoubleArr(args));
	    return true;
	} else if (name.equals("pos")) {
	    if (args.length != 3) {
		System.out.println("bad parameters");
		return false;
	    }
	    position = new Point3D(Parser.stringArrToDoubleArr(args));
	    return true;
	} else if (name.equals("attenuation")) {
	    if (args.length != 3) {
		System.out.println("bad parameters");
		return false;
	    }
	    attenuation = new Vector(Parser.stringArrToDoubleArr(args));
	    return true;
	}

	// We didn't find any parameter
	return false;
    }

    public boolean finalizeObject() {
	if (position == null) {
	    System.out.println("Error: one or more parameters are missing");
	    return false;
	}

	return true;
    }

    @Override
    public boolean isCamera() {
	return false;
    }

    public boolean isLight() {
	return true;
    }

    @Override
    public Ray buildRayFrom(Point3D p) {
	return new Ray(p, position);
    }

    @Override
    public ColorRGB getIllumination(Point3D p) {
	double distance = position.distance(p);
	double factor = attenuation.getX() + attenuation.getY() * distance + attenuation.getZ() * distance * distance;

	return color.multiply(1 / factor);
    }

    public double getDistanceFromPoint(Point3D p) {
	return position.distance(p);
    }

    @Override
    public List<lightObject> getLightSources() {
	List<lightObject> l = new ArrayList<lightObject>();
	l.add(this);
	return l;
    }
}
